﻿using System.Collections.ObjectModel;
using System.Reflection;
using System.Windows.Markup.Localizer;
using Prism.Commands;
using Prism.Services.Dialogs;
using SmartPlant.Core;
using SmartPlant.Core.Mvvm;
using SmartPlant.Model;
using SmartPlant.Model.Biz;
using SmartPlant.Modules.Base.UIEntity;
using SmartPlant.Services;
using SmartPlant.Services.Interfaces;
using SmartPlant.WinCore;
using Telerik.Windows.Documents.FormatProviders.Html.Parsing.Dom;
using Unity;

namespace SmartPlant.Modules.Base.ViewModels
{
    internal class CommonPropertyViewModel : DialogViewModelBase
    {
        private readonly ICodeListService _codeListService;
        private readonly IProjectService _projectService;
        private readonly IDialogUIService dialogUIService;
        private readonly IInstrumentService instrumentService;
        private readonly IPDGeneralService pdServ;
        private readonly ILoopService loopService;
        private ObjectDefId _objectType;
        private decimal _proId;
        private string _targetId;
        private dynamic _targetObj;

        /// <summary>
        /// dialog-ui接口返回的数据
        /// </summary>
        private List<List<ViewQueryItemAttr>> _viewQueryItems;
        private bool isBusy = true;
        public bool IsBusy
        {
            get { return isBusy; }
            set
            {
                isBusy = value;
                RaisePropertyChanged();
            }
        }
        public DelegateCommand<int?> SelectionChangedCommand { get; set; }

        public CommonPropertyViewModel(IUnityContainer unityContainer, IProjectService projectService, IDialogService dialogService, ICodeListService codeListService)
            : base(dialogService)
        {
            loopService = unityContainer.Resolve<LoopService>();
            dialogUIService = unityContainer.Resolve<DialogUIService>();
            instrumentService = unityContainer.Resolve<InstrumentService>();
            pdServ = unityContainer.Resolve<PDGeneralService>();
            InitViewsCommand = new DelegateCommand(InitViews);
            OkCommand = new DelegateCommand(Ok);
            _projectService = projectService;
            _codeListService = codeListService;
            TabItemModel commonTab = new TabItemModel("通用");
            TabItemModel PSTab = new TabItemModel("工艺参数");
            TabItemModel UDFTab = new TabItemModel("UDF");
            TabItemModel UDTTab = new TabItemModel("UDT");
            TabViewItems = new ObservableCollection<TabItemModel> { commonTab, PSTab, UDFTab, UDTTab };
            SelectionChangedCommand = new DelegateCommand<int?>(SelectionChanged);
        }

        private async void SelectionChanged(int? index)
        {
            switch (index)
            {
                case 0:
                    await InitViewsCore(0, _targetObj);
                    break;
                case 1:
                    await InitViewsCore(1, _targetObj.PdGenerals[0]);
                    break;
                case 2:
                    await InitViewsCore(2, _targetObj.UDF);
                    break;
                case 3:
                    await InitViewsCore(3, _targetObj);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// xaml里绑定到loaded时
        /// </summary>
        public DelegateCommand InitViewsCommand { get; set; }
        public DelegateCommand OkCommand { get; set; }

        private ObservableCollection<TabItemModel> _TabViewItems;
        /// <summary>
        /// 和前端绑定的，tab页
        /// </summary>
        public ObservableCollection<TabItemModel> TabViewItems
        {
            get { return _TabViewItems; }
            set
            {
                _TabViewItems = value;
                RaisePropertyChanged();
            }
        }

        public async void InitViews()
        {
            TabItemModel commonTab = new TabItemModel("通用");
            TabItemModel PSTab = new TabItemModel("工艺参数");
            TabItemModel UDFTab = new TabItemModel("UDF");
            TabItemModel UDTTab = new TabItemModel("UDT");

            IsBusy = true;
            _viewQueryItems = await dialogUIService.GetDialogUiAsync(_proId, (int)DialogPurpose, _objectType.ToString());
            switch (_objectType)
            {
                case ObjectDefId.loop:
                    TabViewItems.Clear();
                    TabViewItems = new ObservableCollection<TabItemModel> { commonTab };
                    if (_viewQueryItems.Count != 1) //1个元素
                    {
                        throw new Exception($"{nameof(dialogUIService)} tab ui count != 4");
                    }
                    _targetObj = string.IsNullOrEmpty(_targetId) ? new Loop() : await loopService.GetLoopAsync(_proId, _targetId);
                    break;

                case ObjectDefId.component:
                    TabViewItems.Clear();
                    TabViewItems = new ObservableCollection<TabItemModel> { commonTab, PSTab, UDFTab, UDTTab };
                    if (_viewQueryItems.Count != 4) //4个元素
                    {
                        throw new Exception($"{nameof(dialogUIService)} tab ui count != 4");
                    }
                    //目前就只有第一个tab的数据，还需要pdgeneral、UDF、UDT那些tab的数据
                    _targetObj = string.IsNullOrEmpty(_targetId) ? new Instruments() : await instrumentService.GetInstrumentAsync(_proId, _targetId);
                    break;

                default:
                    break;
            }

            //每个tab页要用的数据源不一样
            SelectionChanged(0);
            #region ContentItemModel demo

            //{
            //    ContentItems = new ObservableCollection<ContentItemModel>
            //    {
            //        new ContentItemModel("文本", ContentItemType.Text)
            //        {
            //        },
            //        new ContentItemModel("只读文本", ContentItemType.Text)
            //        {
            //            IsReadOnly = true
            //        },
            //        new ContentItemModel("下拉项", ContentItemType.Combox)
            //        {
            //            Items = new(),
            //            IsReadOnly = true
            //        },
            //        new ContentItemModel("文本加下拉", ContentItemType.TextCombox)
            //        {
            //            Item = "文本",
            //            Items = new()
            //        }
            //    }
            //};

            #endregion ContentItemModel demo
            IsBusy = false;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="i">tab的顺序，从0开始</param>
        private async Task InitViewsCore(int i, dynamic _targetObj)
        {
            //每个tab页要用的数据源不一样
            if (TabViewItems[i].ContentItems.Count > 0)
            {
                return;
            }
            foreach (ViewQueryItemAttr item in _viewQueryItems[i].Where(p => p.IsDisplayed == 1))
            {
                ContentItemType it = item.WPF_IsDropDown ? ContentItemType.Combox : ContentItemType.Text;
                if (item.UoM != null)
                {
                    it = ContentItemType.TextCombox; //单位，既有值，又有下拉
                }
                ContentItemModel contentItemModel = new ContentItemModel(item.WPF_UniqueName, item.SPIColName.ToUpper(), item.DisplayName, it, item.WPF_readonlymask == "3");

                switch (it)
                {
                    case ContentItemType.Combox:
                        var y = await _codeListService.GetDropDownListByAttrAsync(item.ItemattributionId);
                        var selectedyItem = y.FirstOrDefault(p => p.Id == Reflect.GetPropValue(_targetObj, item.WPF_UniqueName)?.ToString()); //_targetObj.GetType().GetProperty(contentItemModel.PropertyName)?.GetValue(_targetObj, null)?.ToString()
                        contentItemModel.Items.AddRange(y);
                        contentItemModel.SelectedItem = selectedyItem;
                        contentItemModel.Value = "";
                        break;

                    case ContentItemType.TextCombox:
                        var x = await _codeListService.GetDropDownListByAttrAsync(item.UoM.ItemattributionId);
                        var uomValue = Reflect.GetPropValue(_targetObj, item.UoM.WPF_UniqueName)?.ToString();
                        var selectedxItem = x.FirstOrDefault(p => p.Id == uomValue || p.Name == uomValue);
                        contentItemModel.Items.AddRange(x);
                        contentItemModel.SelectedItem = selectedxItem;
                        contentItemModel.PropertyUoMName = item.UoM.WPF_UniqueName;
                        if (_targetObj != null)
                        {
                            contentItemModel.Value = Reflect.GetPropValue(_targetObj, contentItemModel.PropertyName)?.ToString();
                        }
                        break;

                    case ContentItemType.Text:
                        if (_targetObj != null)
                        {
                            //GetProperty时，大小写，_ 这些都要确保一致
                            contentItemModel.Value = Reflect.GetPropValue(_targetObj, contentItemModel.PropertyName)?.ToString();
                        }
                        break;
                }
                TabViewItems[i].ContentItems.Add(contentItemModel);
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="Ins">数据的本体，如Instrument类的一个变量</param>
        /// <param name="item">一个窗体里某个Tab对应的数据体，里面有每个单元格的数据</param>
        private void UpdatePropCore(ref dynamic Ins, TabItemModel item)
        {
            foreach (var attr in item.ContentItems.Where(x => x.IsReadOnly == false)) //不要只读的
            {
                PropertyInfo attrDef = Reflect.GetProperty(Ins.GetType(), attr.PropertyName); //Ins.GetType().GetProperty(attr.PropertyName);
                if (attrDef != null)
                {
                    object value;
                    switch (attr.Type)
                    {
                        case ContentItemType.Text:
                            value = Reflect.ConvertStringToPropertyType(attrDef, attr.Value);
                            attrDef.SetValue(Ins, value, null); //字符串 转 decimal 的问题
                            break;
                        case ContentItemType.Combox:
                            value = Reflect.ConvertStringToPropertyType(attrDef, attr.SelectedItem?.Id); //下拉
                            //decimal _id = Convert.ToDecimal(attr.SelectedItem?.Id);//不一定就是数字，比如下拉列表可能从
                            attrDef.SetValue(Ins, value, null); //字符串 转 decimal 的问题
                            break;
                        case ContentItemType.TextCombox: //这里是对单位的更新
                            //decimal _item = Convert.ToDecimal(attr.Item);
                            value = Reflect.ConvertStringToPropertyType(attrDef, attr.Value);
                            attrDef.SetValue(Ins, value, null); //字符串 转 decimal 的问题

                            var attrUoMDef = Reflect.GetProperty(Ins.GetType(), attr.PropertyUoMName); // Ins.GetType().GetProperty(attr.PropertyUoMName);
                            //decimal _id1 = Convert.ToDecimal(attr.SelectedItem?.Id);
                            value = Reflect.ConvertStringToPropertyType(attrUoMDef, attr.SelectedItem?.Id); //下拉
                            Reflect.SetPropValue(Ins, attr.PropertyUoMName, value); // Ins.GetType().GetProperty("UOM_ID").SetValue(Ins, _id1, null);
                            //还要考虑里面的UOM的更新

                            break;
                        default:
                            break;
                    }
                }
            }
        }

        public override void OnDialogOpened(IDialogParameters parameters)
        {
            base.OnDialogOpened(parameters);
            _proId = GlobalObject.CurrentProject.ProjId;
            _targetId = parameters.GetValue<string>(DialogParameterKeys.Id);
            _objectType = parameters.GetValue<ObjectDefId>(DialogParameterKeys.ObjectType);
            IsBusy = false;
        }

        /// <summary>
        /// ok按钮，相当于确认更新
        /// </summary>
        private async void Ok()
        {
            IsBusy = true;

            bool result = false;
            switch (_objectType)
            {
                case ObjectDefId.loop:
                    //case ObjectType.Loop:
                    //                                   result = await loopService.CreateLoopAsync(_proId, _targetObj as Loop);
                    //                                   break;
                    //result = await loopService.CreateLoopAsync(_proId, _targetObj as Loop);
                    //result = await loopService.UpdateLoopAsync(_proId, _targetObj as Loop);
                    UpdatePropCore(ref _targetObj, TabViewItems[0]);
                    var Loop = _targetObj as Loop;
                    switch (DialogPurpose)
                    {
                        case DialogPurpose.Update:
                        case DialogPurpose.Create:
                            await loopService.UpdateLoopAsync(_proId, Loop);
                            break;
                        case DialogPurpose.Copy:
                            break;
                        case DialogPurpose.Delete:
                            break;
                        case DialogPurpose.None:
                            break;
                        default:
                            break;
                    }
                    break;
                case ObjectDefId.component:

                    //回写所有属性 问题 不知道原始属性的数据类型是什么 会出问题

                    UpdatePropCore(ref _targetObj, TabViewItems[0]);
                    UpdatePropCore(ref _targetObj.PdGenerals[0], TabViewItems[1]);
                    UpdatePropCore(ref _targetObj.UDF, TabViewItems[2]);
                    UpdatePropCore(ref _targetObj, TabViewItems[3]);
                    var Ins = _targetObj as Instruments;
                    switch (DialogPurpose)
                    {
                        case DialogPurpose.Create:
                            //新建后，也是打开的属性窗口 
                        case DialogPurpose.Copy: 
                        case DialogPurpose.Update:
                            var task7 = Task.Run(async () => await instrumentService.UpdateInstrumentAsync(_proId, Ins));//通用和UDT 两个TAB
                            var task8 = Task.Run(async () => await instrumentService.UpdateUDFAsync(_proId, Ins.UDF));//UDF
                            var task9 = Task.Run(async () => await pdServ.UpdateProcessDataAsync(_proId, Ins.PdGenerals[0])); //工艺参数
                            var taskAll3 = new List<Task<bool>>() { task7, task8, task9 };
                            await Task.WhenAll(taskAll3);
                            break;
                    }
                    break;
                default:
                    break;
            }
            RaiseRequestClose(new DialogResult(ButtonResult.OK, parameters: new DialogParameters { { DialogParameterKeys.Content, _targetObj } }));
            IsBusy = false;
        }
    }
}
